<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Peaks.js Demo Page</title>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <div id="titles">
      <h1>Peaks.js</h1>
      <p>
        Peaks.js is a JavaScript library that allows you to display and
        interact with audio waveforms in the browser.
      </p>

      <h2>Demo pages</h2>
      <p>
        The following pages demonstrate various configuration options:
      </p>
      <p>
        <a href="/index.html">Precomputed Waveform Data</a> |
        <a href="/webaudio.html">Web Audio API</a> |
        <a href="/zoomable-waveform.html">Single Zoomable Waveform</a> |
        <a href="/overview-waveform.html">Single Fixed Waveform</a> |
        Cue Events |
        <a href="/set-source.html">Changing the Media URL</a> |
        <a href="/multi-channel.html">Multi-Channel Waveform</a> |
        <a href="/custom-markers">Custom Point and Segment Markers</a> |
        <a href="/overlay-segments.html">Overlay Segments</a> |
        <a href="/external-player.html">External Audio Player</a> |
        <a href="/scrollbar.html">Scrollbar</a>
      </p>

      <h2>Demo: Cue Events</h2>
      <p>
        This demo shows how to listen for events from the playhead reaching points, or segment edges. <br />
        Events in this demo are logged in the browser console.
      </p>
    </div>

    <div class="waveform-container">
      <div id="zoomview-container"></div>
    </div>
    <div class="waveform-container">
      <div id="overview-container"></div>
    </div>

    <div id="demo-controls">
      <audio id="audio" controls="controls">
        <source src="/TOL_6min_720p_download.mp3" type="audio/mpeg">
        <source src="/TOL_6min_720p_download.ogg" type='audio/ogg; codecs="vorbis"'>
        Your browser does not support the audio element.
      </audio>

      <div id="controls">
        <div>
          <button data-action="zoom-in">Zoom in</button>
          <button data-action="zoom-out">Zoom out</button>
          <button data-action="add-segment">Add Segment</button>
          <button data-action="add-point">Add Point</button>
          <button data-action="log-data">Log segments/points</button>
        </div>
        <div>
          <input type="text" id="seek-time" value="0.0">
          <button data-action="seek">Seek</button>
          <button data-action="reverse-direction">Reverse direction</button>
          <button data-action="destroy">Destroy</button>
        </div>
      </div>
    </div>

    <div class="log">
      <div id="segments" class="hide">
        <h2>Segments</h2>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>Label</th>
              <th>Start time</th>
              <th>End time</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
          </tbody>
        </table>
      </div>

      <div id="points" class="hide">
        <h2>Points</h2>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>Label</th>
              <th>Time</th>
            </tr>
          </thead>
          <tbody>
          </tbody>
        </table>
      </div>
    </div>

    <script src="/peaks.js"></script>
    <script>
      (function(Peaks) {
        var renderSegments = function(peaks) {
          var segmentsContainer = document.getElementById('segments');
          var segments = peaks.segments.getSegments();
          var html = '';

          for (var i = 0; i < segments.length; i++) {
            var segment = segments[i];

            var row = '<tr>' +
              '<td>' + segment.id + '</td>' +
              '<td><input data-action="update-segment-label" type="text" value="' + segment.labelText + '" data-id="' + segment.id + '"/></td>' +
              '<td><input data-action="update-segment-start-time" type="number" value="' + segment.startTime + '" data-id="' + segment.id + '"/></td>' +
              '<td><input data-action="update-segment-end-time" type="number" value="' + segment.endTime + '" data-id="' + segment.id + '"/></td>' +
              '<td>' + '<a href="#' + segment.id + '" data-action="play-segment" data-id="' + segment.id + '">Play</a>' + '</td>' +
              '<td>' + '<a href="#' + segment.id + '" data-action="remove-segment" data-id="' + segment.id + '">Remove</a>' + '</td>' +
              '</tr>';

            html += row;
          }

          segmentsContainer.querySelector('tbody').innerHTML = html;

          if (html.length) {
            segmentsContainer.classList.remove('hide');
          }

          document.querySelectorAll('input[data-action="update-segment-start-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);

              if (segment) {
                var startTime = parseFloat(element.value);

                if (startTime < 0) {
                  startTime = 0;
                  element.value = 0;
                }

                if (startTime >= segment.endTime) {
                  startTime = segment.endTime - 0.1;
                  element.value = startTime;
                }

                segment.update({ startTime: startTime });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-segment-end-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);

              if (segment) {
                var endTime = parseFloat(element.value);

                if (endTime < 0) {
                  endTime = 0;
                  element.value = 0;
                }

                if (endTime <= segment.startTime) {
                  endTime = segment.startTime + 0.1;
                  element.value = endTime;
                }

                segment.update({ endTime: endTime });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-segment-label"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);
              var labelText = element.labelText;

              if (segment) {
                segment.update({ labelText: labelText });
              }
            });
          });
        };

        var renderPoints = function(peaks) {
          var pointsContainer = document.getElementById('points');
          var points = peaks.points.getPoints();
          var html = '';

          window.pointUpdated = function(i, prop, value) {
            var points = peaksInstance.points.getPoints();
            var segment = points[i];
            point.update({[prop]: value});
          };

          for (var i = 0; i < points.length; i++) {
            var point = points[i];

            var row = '<tr>' +
              '<td>' + point.id + '</td>' +
              '<td><input data-action="update-point-label" type="text" value="' + point.labelText + '" data-id="' + point.id + '"/></td>' +
              '<td><input data-action="update-point-time" type="number" value="' + point.time + '" data-id="' + point.id + '"/></td>' +
              '<td>' + '<a href="#' + point.id + '" data-action="remove-point" data-id="' + point.id + '">Remove</a>' + '</td>' +
              '</tr>';

            html += row;
          }

          pointsContainer.querySelector('tbody').innerHTML = html;

          if (html.length) {
            pointsContainer.classList.remove('hide');
          }

          document.querySelectorAll('input[data-action="update-point-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var point = peaks.points.getPoint(id);

              if (point) {
                var time = parseFloat(element.value);

                if (time < 0) {
                  time = 0;
                  element.value = 0;
                }

                point.update({ time: time });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-point-label"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var point = peaks.points.getPoint(id);
              var labelText = element.labelText;

              if (point) {
                point.update({ labelText: labelText });
              }
            });
          });
        };

        var options = {
          zoomview: {
            container: document.getElementById('zoomview-container')
          },
          overview: {
            container: document.getElementById('overview-container')
          },
          mediaElement: document.getElementById('audio'),
          dataUri: {
            arraybuffer: '/TOL_6min_720p_download.dat',
            json: '/TOL_6min_720p_download.json'
          },
          keyboard: true,
          pointMarkerColor: '#006eb0',
          showPlayheadTime: true,
          emitCueEvents: true
        };

        Peaks.init(options, function(err, peaksInstance) {
          if (err) {
            console.error(err.message);
            return;
          }

          console.log("Peaks instance ready");

          document.querySelector('[data-action="zoom-in"]').addEventListener('click', function() {
            peaksInstance.zoom.zoomIn();
          });

          document.querySelector('[data-action="zoom-out"]').addEventListener('click', function() {
            peaksInstance.zoom.zoomOut();
          });

          document.querySelector('button[data-action="add-segment"]').addEventListener('click', function() {
            peaksInstance.segments.add({
              startTime: peaksInstance.player.getCurrentTime(),
              endTime: peaksInstance.player.getCurrentTime() + 2,
              labelText: "Test segment",
              editable: true
            });
          });

          document.querySelector('button[data-action="add-point"]').addEventListener('click', function() {
            peaksInstance.points.add({
              time: peaksInstance.player.getCurrentTime(),
              labelText: "Test point",
              editable: true
            });
          });

          document.querySelector('button[data-action="log-data"]').addEventListener('click', function(event) {
            renderSegments(peaksInstance);
            renderPoints(peaksInstance);
          });

          document.querySelector('button[data-action="seek"]').addEventListener('click', function(event) {
            var time = document.getElementById('seek-time').value;
            var seconds = parseFloat(time);

            if (!Number.isNaN(seconds)) {
              peaksInstance.player.seek(seconds);
            }
          });

          document.querySelector('button[data-action="reverse-direction"]').addEventListener('click', function(event) {
            var el = document.querySelector('audio');

            try {
              el.playbackRate = -el.playbackRate;
            }
            catch (e) {
              console.info('reverse direction not supported');
            }
          });

          document.querySelector('button[data-action="destroy"]').addEventListener('click', function(event) {
            peaksInstance.destroy();
          });

          document.querySelector('body').addEventListener('click', function(event) {
            var element = event.target;
            var action  = element.getAttribute('data-action');
            var id      = element.getAttribute('data-id');

            if (action === 'play-segment') {
              var segment = peaksInstance.segments.getSegment(id);
              peaksInstance.player.playSegment(segment);
            }
            else if (action === 'remove-point') {
              peaksInstance.points.removeById(id);
            }
            else if (action === 'remove-segment') {
              peaksInstance.segments.removeById(id);
            }
          });

          peaksInstance.segments.add({
            startTime: 5.5,
            endTime: 7.5,
            editable: true,
            id: 'testsegment'
          });

          peaksInstance.points.add({
            time: 4.3,
            editable: true,
            id: 'testpoint'
          });

          peaksInstance.on('points.enter', function(event) {
            console.log('points.enter', event);
          });

          peaksInstance.on('segments.enter', function(event) {
            console.log('segments.enter', event);
          });

          peaksInstance.on('segments.exit', function(event) {
            console.log('segments.exit', event);
          });
        });
      })(peaks);
    </script>
  </body>
</html>
